import React from 'react'
import PropTypes from 'prop-types'
import {Icon, notification, Modal} from 'antd'
import axios from 'axios'
import classNames from 'classnames'
import styles from './index.less'

import {uploadToken} from '../../services/upload'

export default class Upload extends React.Component {
  constructor(props) {
    super(props)
    const {value = []} = props
    this.state = {
      fileList: value,
      activeItem: {}
    }
    this.payload = {
      token: ''
    }
  }

  static propTypes = {
    action: PropTypes.string,
    beforeUpload: PropTypes.func,
    onChange: PropTypes.func,
    onRemove: PropTypes.func,
    value: PropTypes.array,
    multiple: PropTypes.bool,
    limit: PropTypes.number
  }

  static defaultProps = {
    action: 'https://upload.qiniup.com',
    multiple: false,
    limit: 1
  }

  beforeUpload = async () => {
    const {beforeUpload} = this.props
    this.payload.token = await uploadToken()
    if (beforeUpload) {
      await beforeUpload()
    }
    this.input.click()
  }

  startUpload = async (file) => {
    const {action} = this.props
    const fd = new FormData()
    Object.entries(this.payload).forEach(([key, value]) => {
      fd.append(key, value)
    })
    fd.append('file', file)
    const {data} = await axios({
      url: action,
      method: 'post',
      data: fd
    })
    const {base_url, path} = data
    data.url = `${base_url + path}-300x300`
    return data
  }

  onChange = async () => {
    const {files = []} = this.input
    for (let i = 0; i < files.length; i++) {
      try {
        const res = await this.startUpload(files[i])
        this.setState({
          fileList: [...this.state.fileList, res]
        })
        const {onChange} = this.props
        if (onChange) onChange(this.state.fileList)
      } catch (e) {
        const {message, response = {}} = e
        const {error} = response.data || {}
        notification.error({
          message: error || message
        })
      }
      this.input.value = ''
    }
  }

  preView = (item) => {
    this.setState({
      activeItem: item
    })
  }

  handleCancel = () => {
    this.setState({
      activeItem: {}
    })
  }

  onRemove = (item, index) => {
    const {onRemove, onChange} = this.props
    const {fileList} = this.state
    if (onRemove) {
      onRemove(item)
    }
    const list = fileList.filter((item, i) => i !== index)
    if (onChange) {
      onChange(list)
    }
    this.setState({
      fileList: list
    })
  }

  renderCards = () => {
    const {fileList} = this.state
    return fileList.map((value, i) => (
      <div
        key={i} className={classNames(styles.inner, styles.card)}
        style={{background: `url(${value.url}) no-repeat center center`}}
      >
        <div
          className={styles.iconWrap}>
          <Icon
            type="eye" theme="outlined"
            onClick={() => this.preView(value)}
          />
          <Icon
            type="delete" theme="outlined"
            onClick={() => this.onRemove(value, i)}
          />
        </div>
      </div>
    ))
  }

  renderUpload = () => {
    return (
      <div onClick={this.beforeUpload} className={styles.upload}>
        <div className={styles.inner}>
          <Icon type="plus" />
          <div className="ant-upload-text">上传</div>
        </div>
      </div>
    )
  }

  render() {
    const {multiple, limit} = this.props
    const {fileList, activeItem} = this.state
    return (
      <div className={styles.container}>
        <div className="flex">
          {this.renderCards()}
          {limit > fileList.length && this.renderUpload()}
          <input
            multiple={multiple}
            ref={n => this.input = n} type="file" className={styles.input}
            onChange={this.onChange}
          />
        </div>
        <Modal visible={!!activeItem.url} footer={null} onCancel={this.handleCancel}>
          {activeItem.url && <img alt="preview" style={{width: '100%'}} src={`${activeItem.url.replace('-300x300', '-w750n')}`} />}
        </Modal>
      </div>
    )
  }
}
